﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotSpatial.Controls;
using DotSpatial.Controls.Header;
using ShadingTab.Properties;
using System.Windows.Forms;
using DotSpatial.Data;
using DotSpatial.Topology;
using System.Drawing;
using DotSpatial.Symbology;
using System.Data.OleDb;
using System.Data;
using System.Collections;
using System.IO;

using DotSpatial.Projections;
using System.Xml;
using System.Globalization;



namespace ShadingTab
{
	public class MainClass : Extension
    {

        #region classes Shading tab references

        UtilityFunctions util = new UtilityFunctions();
        public ProjectVariables prj = new ProjectVariables();
        #endregion

        #region Variables
        bool firstBldgPt = false;
        List<Coordinate> BldgCoords = new List<Coordinate>();
        Coordinate lastCoord;
        frmAddBuilding FormAddBuilding;
        frmAddBuilding FormAddBldg;
        const int nSta = 239;
        struct weatherSta
        {
            public string CODE;
            public string State;
            public string City;
            public double LAT;
            public double LONG;
            public double Elev;
            public string FileName;
            public double LAT2;
            public double LONG2;
        }
        weatherSta[] wSta = new weatherSta[nSta];
        double[] wStaDistance = new double[nSta];
        int[] wStaSel = new int[nSta];
        public bool pickBLLocation = false;
        bool siteLocatedbyCentroid = false;
        IMap map;
        
        #endregion end Variables
      

        enum mapAction
        {
            None, Select, pickRoseLocation, firstRidgePoint, SecondRidgePoint, firstEavePoint, SecondEavePoint,
            BuildingCoord, EndBuildingCoord, SelectBuilding, AreaCoord, AlignmentCoord1, AlignmentCoord2, MovePanelCoord
        };
        mapAction mapAct = new mapAction();

		public override void Activate()
        {
			base.Activate();
            map = App.Map;
            Map mp = App.Map as Map;
            mp.MouseDown += map_MouseDown;
            mp.MouseMove += map_MouseMove;
            #region Button creation

            const string ShadingTab = "Shading";
            App.HeaderControl.Add(new RootItem(ShadingTab, "Shading") { SortOrder = 205 });

			// Create and add Download button
            SimpleActionItem btnAddBuilding = new SimpleActionItem("Add Building", addBuildingClick);
            btnAddBuilding.RootKey = ShadingTab;
            btnAddBuilding.ToolTipText = "Draw new buildings";
            btnAddBuilding.GroupCaption = "Buildings";
            btnAddBuilding.LargeImage = Resources.AddBuilding64x64;
            App.HeaderControl.Add(btnAddBuilding);

            SimpleActionItem btnSelectBuilding = new SimpleActionItem("Select Buildings", selectBuildingClick);
            btnSelectBuilding.RootKey = ShadingTab;
            btnSelectBuilding.ToolTipText = "Select buildings to edit";
            btnSelectBuilding.GroupCaption = "Buildings";
            btnSelectBuilding.SmallImage = Resources.selectBuilding24x24;
            App.HeaderControl.Add(btnSelectBuilding);

            SimpleActionItem btnEditBldgAttr = new SimpleActionItem("Edit Attributes", editBldgAttrClick);
            btnEditBldgAttr.RootKey = ShadingTab;
            btnEditBldgAttr.ToolTipText = "Edit attributes of selected buildings";
            btnEditBldgAttr.GroupCaption = "Buildings";
            btnEditBldgAttr.SmallImage = Resources.attributeTable24x24;
            App.HeaderControl.Add(btnEditBldgAttr);

            SimpleActionItem btnAddTrees = new SimpleActionItem("Add Trees", addTreeClick);
            btnAddTrees.RootKey = ShadingTab;
            btnAddTrees.ToolTipText = "Draw new Trees";
            btnAddTrees.GroupCaption = "Trees";
            btnAddTrees.LargeImage = Resources.AddTree64x64;
            App.HeaderControl.Add(btnAddTrees);

            SimpleActionItem btnSelectTree = new SimpleActionItem("Select Trees", selectTreeClick);
            btnSelectTree.RootKey = ShadingTab;
            btnSelectTree.ToolTipText = "Select buildings to edit";
            btnSelectTree.GroupCaption = "Trees";
            btnSelectTree.SmallImage = Resources.selectTree;
            App.HeaderControl.Add(btnSelectTree);

            SimpleActionItem btnEditTreeAttr = new SimpleActionItem("Edit Attributes", editTreeAttrClick);
            btnEditTreeAttr.RootKey = ShadingTab;
            btnEditTreeAttr.ToolTipText = "Edit attributes of selected buildings";
            btnEditTreeAttr.GroupCaption = "Trees";
            btnEditTreeAttr.SmallImage = Resources.attributeTable24x24;
            App.HeaderControl.Add(btnEditTreeAttr);

            SimpleActionItem btnExport3D = new SimpleActionItem("Export kmz", export3DClick);
            btnExport3D.RootKey = ShadingTab;
            btnExport3D.ToolTipText = "Export a 3D rendering of buildings and trees";
            btnExport3D.GroupCaption = "3D Export";
            btnExport3D.LargeImage = Resources.selectTree;
            App.HeaderControl.Add(btnExport3D);
         //   btnExport3D.Enabled = false;
            // todo: enable 3D export once a building or tree is created


            SimpleActionItem sunRosebtn = new SimpleActionItem("Draw SunRose Diagram", onSunRoseClick);
            sunRosebtn.RootKey = ShadingTab;
            sunRosebtn.ToolTipText = "Draw the Sun Rose Diagram";
            sunRosebtn.GroupCaption = "Solar Visualization";
            sunRosebtn.LargeImage = Resources.sun;
            App.HeaderControl.Add(sunRosebtn);

            SimpleActionItem sunRoseDatabtn = new SimpleActionItem("Plot SunRose Table", onSunRoseDataClick);
            sunRoseDatabtn.RootKey = ShadingTab;
            sunRoseDatabtn.ToolTipText = "Draw the Sun Rose Diagram";
            sunRoseDatabtn.GroupCaption = "Solar Visualization";
            sunRoseDatabtn.LargeImage = Resources.sun;
            App.HeaderControl.Add(sunRoseDatabtn);


            #endregion button creation

            
		}


        void export3DClick(object sender, EventArgs e)
        {

            //check to see if data has been imported
            Class3dExport exp3d = new Class3dExport();
            exp3d.prj = prj;
            exp3d.map = map;
            exp3d.util = util;

            exp3d.ExportBldgAndTrr2SketchUp_Click(sender,e);

          //  MessageBox.Show("3D");
            return;
        }
        

        public void onSunRoseClick(object sender, EventArgs e)
        {
            DrawRoseDiagram();
            return;
        }

        public void onSunRoseDataClick(object sender, EventArgs e)
        {
            frmSunPath frmSunpath = new frmSunPath();
            frmSunpath.Project = prj;
            frmSunpath.ShowDialog();
            
            return;
        }

		public override void Deactivate() 
        {
			App.HeaderControl.RemoveAll();
			base.Deactivate();
		}

        
		void addBuildingClick(object sender, EventArgs e) 
        {
         
			//open AddBuilding form
            
            FormAddBldg = new frmAddBuilding(this,prj);
            FormAddBldg.Show();
            map.FunctionMode = FunctionMode.Select;
            mapAct = mapAction.BuildingCoord;
            FormAddBldg.Focus();
            firstBldgPt = true;
            FormAddBldg.TopMost = true;
            
            //==========Create building layer ======================
            bool lyrExists = util.checkLyr("Building", App.Map);
            if (lyrExists == false)
            {

                IFeatureSet fs;
                fs = new FeatureSet(FeatureType.Polygon);
                fs.Projection = map.Projection;
                fs.DataTable.Columns.Add(new DataColumn("Height", typeof(double)));
                fs.DataTable.Columns.Add(new DataColumn("Remark", typeof(double)));

                //++++++++++++++++++++++++++++++++++++++++++++++++++++++
                fs.Name = "Building";
                fs.Filename = "C:\\" + "\\Temp\\" + fs.Name + ".shp";
                //++++++++++++++++++++++++++++++++++++++++++++++++++++++

                fs.SaveAs(fs.Filename, true);
                //util.removeDupplicateLyr(fs.Name, pvMap);
                map.Layers.Add(fs);
                prj.LyrBuildingName = fs.Name;
                //loadLayerList();
                // set current layer to building layer
                setCurrrentLayer(prj.LyrBuildingName);
            }
            //============End Create Building Layer===========================
            //btnExport3D.Enabled = true;
			return;

        }

        void selectBuildingClick(object sender, EventArgs e) 
        {
			//check to see if data has been imported
            MessageBox.Show("selectBuildingClick");
			return;
        }

        void editBldgAttrClick(object sender, EventArgs e) 
        {
			//check to see if data has been imported
            MessageBox.Show("editBldgAttrClick");
			return;
        }

        void addTreeClick(object sender, EventArgs e) 
        {
			//check to see if data has been imported
            MessageBox.Show("addTreeClick");
			return;
        }

        void selectTreeClick(object sender, EventArgs e)
        {
            //check to see if data has been imported
            MessageBox.Show("selectTreeClick");
            return;
        }

        void editTreeAttrClick(object sender, EventArgs e) 
        {
			//check to see if data has been imported
            MessageBox.Show("editTreeAttrClick");
			return;
		}

       

        bool setCurrrentLayer(string LyrName)
        {
            
            int i = util.getLayerHdl(LyrName, map);
            if (i == -1)
            {
                MessageBox.Show("Please select layer to assign as current layer first");
                return false;
            }
            else
            {
                for (int j = 0; j < App.Legend.RootNodes.Count; j++)
                    foreach (ILegendItem lb in App.Legend.RootNodes[j].LegendItems)
                    {
                        if (lb.LegendText == LyrName)
                        {
                            lb.IsSelected = true;
                        }
                        else
                        {
                            lb.IsSelected = false;
                        }
                    }

                map.Layers.SelectedLayer = map.Layers[i];
                map.Layers.SelectLayer(i);// = i;
                //MessageBox.Show(  appManager.Legend.RootNodes.Count.ToString()) ;   
                //MessageBox.Show(appManager.Legend.RootNodes[0].LegendText);
                //MessageBox.Show(appManager.Legend.RootNodes[0].LegendItems.ToString());
                //appManager.Legend.RootNodes[0].LegendItems. =null;
                /**/
                App.Legend.RefreshNodes();
                /**/
                return true;
            }
        }
        
        private void map_MouseDown(object sender, MouseEventArgs e)
         {
            
           FormAddBuilding = FormAddBldg;
          
           
            if (mapAct == mapAction.BuildingCoord)
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (FormAddBuilding.Visible == true)
                    {
                        prj.LyrBuildingName = "Building";
                        if (firstBldgPt == true)
                        {
                            BldgCoords.Clear();
                            firstBldgPt = false;
                        }
                        Coordinate c = new Coordinate();
                        c = map.PixelToProj(e.Location);
                        if (Control.ModifierKeys == Keys.Shift & BldgCoords.Count >= 2)
                        {
                            BldgCoords.Add(new Coordinate(lastCoord));
                        }
                        else
                        {
                            BldgCoords.Add(new Coordinate(c));
                        }
                    }
                }
                if (e.Button == MouseButtons.Right)
                {
                    IFeatureSet fs;
                    int idl = util.getLayerID("Building", map);
                    if (idl == -1) return;
                    setCurrrentLayer("Building");
                    fs = map.Layers[idl].DataSet as IFeatureSet;
                    IPolygon BuildingFe = new DotSpatial.Topology.Polygon(BldgCoords);
                    IFeature ifeaBuilding = fs.AddFeature(BuildingFe);
                    BldgCoords.Clear();
                    firstBldgPt = true;
                    mapAct = mapAction.BuildingCoord;
                    ifeaBuilding.DataRow.BeginEdit();
                    ifeaBuilding.DataRow["Height"] = Convert.ToDouble(FormAddBuilding.txtBuildingHeight.Text);
                    ifeaBuilding.DataRow.EndEdit();
                    fs.Save();
                    util.ClearGraphicMap(map);
                    //-----------------------------------------------------------------------------------------------

                    map.MapFrame.Invalidate();
                }
            }
        }

        private void map_MouseMove(object sender, MouseEventArgs e)
        {
            FormAddBuilding = FormAddBldg;

            
            if (mapAct == mapAction.BuildingCoord)
            {
                if (firstBldgPt == false)
                {
                    util.ClearGraphicMap(map);
                    double x1 = 0;
                    double y1 = 0;
                    double x2 = 0;
                    double y2 = 0;
                    bool piza = false;
                    foreach (Coordinate c in BldgCoords)
                    {
                        x1 = x2;
                        y1 = y2;
                        x2 = c.X;
                        y2 = c.Y;
                        if (piza == true) util.DrawLine(x1, y1, x2, y2, 1, Color.Magenta, map);
                        piza = true;
                    }
                    if (piza == true)
                    {
                        System.Drawing.Point pt = new System.Drawing.Point(e.X, e.Y);
                        Coordinate m = map.PixelToProj(pt);
                        Coordinate p1 = new Coordinate(x1, y1);
                        Coordinate p2 = new Coordinate(x2, y2);
                        double r = Math.Sqrt(Math.Pow((m.X - x2), 2) + Math.Pow((m.Y - y2), 2));
                        double L;
                        if (Control.ModifierKeys == Keys.Shift & BldgCoords.Count >= 2)
                        {
                            Coordinate mm = util.getPerpend(m, p1, p2, out L);
                            double dx = p2.X - mm.X;
                            double dy = p2.Y - mm.Y;
                            util.kDrawCircle(p2, L, 36, map, Color.Yellow);
                            util.DrawLine(p2.X, p2.Y, m.X + dx, m.Y + dy, 1, Color.Magenta, map);
                            lastCoord = new Coordinate(m.X + dx, m.Y + dy);
                            App.ProgressHandler.Progress("Length(m) ", 0, "Length(m): " + L.ToString());
                        }
                        else
                        {
                            util.DrawLine(m.X, m.Y, x2, y2, 1, Color.Magenta, map);
                            App.ProgressHandler.Progress("Length(m) ", 0, "Length(m): " + r.ToString());
                        }
                    }
                }
            }       
        }

        public void drawBuildingShadow()
        {
            IMap map = App.Map;
           
            //CheckWorkingPath();

            //if (prj.Path != "")
            //{
                //if (prj.Verify[3] == true)
                try
                {// int[] dat = new int[mRow, mCol];

                    DateTime today = DateTime.Today;
                    int year =  today.Year;
                    double Latitude = prj.Latiude;
                    double Longitude = prj.Longtitude;
                    double UtmN = prj.UtmN;
                    double UtmE = prj.UtmE;
                    prj.LyrBuilding = util.getLayerHdl(prj.LyrBuildingName, map);
                    if (prj.LyrBuilding != -1)
                    {
                        IFeatureSet fs = new FeatureSet(FeatureType.Polygon);
                        //---------------------------------------------------------
                        fs.DataTable.Columns.Add(new DataColumn("Azimuth", typeof(double)));
                        fs.DataTable.Columns.Add(new DataColumn("Ele_Angle", typeof(double)));
                        //---------------------------------------------------------
                        IMapFeatureLayer mp = map.Layers[prj.LyrBuilding] as IMapFeatureLayer;
                        //MessageBox.Show("Number of shape = " + mp.DataSet.NumRows());

                        //int nShp = mp.DataSet.NumRows() - 1;
                        IFeatureSet myFe;
                        myFe = new FeatureSet(FeatureType.Polygon);

                        IFeatureSet fea = ((IFeatureLayer)map.GetLayers().ToArray()[prj.LyrBuilding]).DataSet;
                        System.Data.DataTable dt = fea.DataTable;

                        for (int ibldg = 0; ibldg < mp.DataSet.NumRows(); ibldg++)
                        {
                            int numBldgPt = mp.DataSet.GetFeature(ibldg).NumPoints;

                            Coordinate[] pts = new Coordinate[numBldgPt];
                            Coordinate[] ptss = new Coordinate[numBldgPt * 2];
                            IFeature blgdFs = mp.DataSet.GetFeature(ibldg);
                            string h1 = blgdFs.DataRow["Height"].ToString();
                            if (util.IsNumeric(h1))
                            {
                                double h = Convert.ToDouble(h1);//dt.Rows[ibldg]["Height"]);

                                for (int i = 0; i < numBldgPt; i++)
                                {
                                    pts[i] = new Coordinate(blgdFs.Coordinates[i].X, blgdFs.Coordinates[i].Y, h);
                                    ptss[i] = new Coordinate(blgdFs.Coordinates[i].X, blgdFs.Coordinates[i].Y);
                                }
                                //--------------------------------------------
                                // Assign building data
                                double x0 = UtmE;
                                double y0 = UtmN;
                                double dx = 20;
                                double dy = 50;
                                //---------------------------------------------

                                short TimeZone = -7;
                                Int32 nightHr = 0;
                                Int32 noonHr = 0;
                                //prgBar.Maximum = 12 * 2 * 24; // frequency about 15 day
                                //prgBar.Visible = true;

                                for (int month = 1; month <= 12; month++)
                                //Parallel.For(1, 12, month =>
                                {
                                    int month_day = System.DateTime.DaysInMonth(2001, month);
                                    for (int day = 1; day <= month_day; day += 7)
                                    {
                                        for (int hr = 0; hr < 24; hr++)
                                        {
                                            //prgBar.PerformStep();

                                            double hrPassMidnight = (double)hr / 24.0;
                                            SolarCal ySolar = new SolarCal(day, month, year, hrPassMidnight, Latitude, Longitude, TimeZone);
                                            //SolarCal ySolar = new SolarCal(day, month, year, hrPassMidnight, Latitude, Longitude, TimeZone);
                                            double eleAng = ySolar.SolarElevationAngle;
                                            double AzAng = ySolar.SolarAzimuthAngle;
                                            //--------------------------------------------------------------
                                            if (eleAng >= prj.EffectiveShadAng) // efficetive elevation angle
                                            {
                                                noonHr++;
                                                //Shadow point
                                                for (int i = 0; i < pts.Length; i++)
                                                {
                                                    Shadow shadow = new Shadow(AzAng, eleAng, pts[i]);
                                                    Coordinate tmp = shadow.shadowPt;
                                                    ptss[i + numBldgPt] = new Coordinate(tmp.X, tmp.Y);
                                                }
                                                // CONVEX HULL Algorithm for make a shadow area
                                                var multiPoint = new MultiPoint(ptss);
                                                var convexHull = (Polygon)multiPoint.ConvexHull();
                                                myFe.AddFeature(convexHull);
                                            }
                                            else // Night hour
                                            {
                                                nightHr++;
                                            }

                                        }
                                    }

                                }//); // Parallel.For
                            }//End if numeric check
                        }

                        Console.WriteLine(DateTime.Now.ToString());
                        Console.ReadLine();

                        //prgBar.Visible = false;   todo: impliment progress bars
                        //IFeatureSet result = myFe.UnionShapes(ShapeRelateType.Intersecting);
                        myFe.Projection = map.Projection;
                        //result.Projection = pvMap.Projection;

                        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                        myFe.Name = "BuildingShadowMap";
                        myFe.Filename = "C:\\" + "\\Temp\\" + myFe.Name + ".shp";
                        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


                        myFe.SaveAs(myFe.Filename, true);
                        //result.Filename =prj.Path + "\\Temp\\shadow map union.shp";
                        //result.SaveAs(result.Filename, true);
                        //pvMap.Layers.Add(myFe);

                        MapPolygonLayer ShadowArea;
                        ShadowArea = new MapPolygonLayer(myFe);// MapPolygonLayer(fs);
                        PolygonSymbolizer ShadowSymboize = new PolygonSymbolizer(Color.Black, Color.Red);
                        // set transparent
                        SimplePattern sp = new SimplePattern(Color.Black);
                        sp.Opacity = 0.5f;
                        ShadowSymboize.Patterns.Clear();
                        ShadowSymboize.Patterns.Add(sp);
                        ShadowArea.Symbolizer = ShadowSymboize;
                        util.removeDupplicateLyr(ShadowArea.Name, map);
                        map.Layers.Add(ShadowArea);
                        MessageBox.Show("Building shadows have been successfully drawn.");
                    }
                    else
                    {
                        MessageBox.Show("Please create a building Layer first.");
                    }
                }
                catch //else
                {
                    MessageBox.Show("Please calculate sun path statistic first.");
                }
            //}
            mapAct = mapAction.None;
        }

        public void CentroidAsSite(string Layer)
        {
            
            if (System.IO.File.Exists(prj.WeatherSta) == false)
            {
                try
                {
                    int cLyr = util.getLayerHdl(Layer, map);
                    FeatureSet Fe = map.Layers[cLyr].DataSet as FeatureSet;
                    Fe.UpdateExtent();
                    double xx = Fe.Extent.X + Fe.Extent.Width / 2;
                    double yy = Fe.Extent.Y - Fe.Extent.Height / 2;

                    Pen MyPen = new Pen(Color.Black);
                    Coordinate c = new Coordinate(xx, yy);
                    Extent ext = map.ViewExtents;
                    double dx = (ext.MaxX - ext.MinX);
                    double dy = (ext.MaxX - ext.MinX);
                    ext.SetCenter(c);
                    map.ViewExtents = ext;// layer.DataSet.Extent;

                    double[] latlong = new double[] { c.X, c.Y };
                    Reproject.ReprojectPoints(latlong, new double[] { 0 }, map.Projection, KnownCoordinateSystems.Geographic.World.WGS1984, 0, 1);
                    prj.Longtitude = Convert.ToDouble(latlong[0].ToString());
                    prj.Latiude = Convert.ToDouble(latlong[1].ToString());
                    double minDist = 1000000.00;

                    for (int i = 0; i < nSta; i++)
                    {
                        double rr;
                        rr = Math.Sqrt(Math.Pow((latlong[0] - wSta[i].LONG2), 2) + Math.Pow((latlong[1] - wSta[i].LAT2), 2));
                        wStaDistance[i] = rr;
                        wStaSel[i] = i;
                        if (rr < minDist)
                        {
                            minDist = rr;
                           // cmbState.Text = wSta[i].State;
                           // cmbCity.Text = wSta[i].City;
                            prj.WeaState = wSta[i].State;
                            prj.WeaCity = wSta[i].City;
                        }
                    }

                    double temp;
                    int temp1;
                    for (int i = (nSta - 2); i >= 0; i--)
                    {
                        for (int j = 1; j <= i; j++)
                        {
                            if (wStaDistance[j - 1] > wStaDistance[j])
                            {
                                temp = wStaDistance[j - 1];
                                wStaDistance[j - 1] = wStaDistance[j];
                                wStaDistance[j] = temp;
                                temp1 = wStaSel[j - 1];
                                wStaSel[j - 1] = wStaSel[j];
                                wStaSel[j] = temp1;
                            }
                        }
                    }

                    //-----------------------------------------------------------------------
                    double radius = 1000;
                    prj.UtmN = c.Y;
                    prj.UtmE = c.X;
                    map.MapFrame.DrawingLayers.Clear();
                    util.kDrawCircle(c.X, c.Y, radius, 360, map, Color.Magenta);
                    //MessageBox.Show(c.X + "," + c.Y);
                    Double r = 0.25;
                    int nIDW = prj.NIdwSta;
                    util.kDrawCircle(c.X, c.Y, r, 360, map, Color.Magenta);
                    prj.UtmE = c.X;
                    prj.UtmN = c.Y;
                    for (int ii = 0; ii < nIDW; ii++)
                    {
                        double lat = wSta[wStaSel[ii]].LAT2;
                        double lng = wSta[wStaSel[ii]].LONG2;
                        double x = 0;
                        double y = 0;
                        double[] mapCoordinate = new double[] { lng, lat };
                        Reproject.ReprojectPoints(mapCoordinate, new double[] { 0 }, KnownCoordinateSystems.Geographic.World.WGS1984, map.Projection, 0, 1);
                        Coordinate coord = util.circleCoord(c.X, c.Y, mapCoordinate[0], mapCoordinate[1], radius); //returns coordinate of point on inner circle
                        Coordinate coord2 = util.circleCoord(mapCoordinate[0], mapCoordinate[1], c.X, c.Y, radius); //returns coordinates of point on outer circle

                        util.kDrawCircle(mapCoordinate[0], mapCoordinate[1], radius, 360, map, Color.Magenta);
                        util.DrawLine(coord2.X, coord2.Y, coord.X, coord.Y, 2, Color.Magenta, map);
                    }

                    Envelope env = new Envelope();
                    env.SetExtents(prj.UtmE - 1000, prj.UtmN - 1000, prj.UtmE + 1000, prj.UtmN + 1000);
                    map.ViewExtents = env.ToExtent();
                    //prj.UseKML = true;
                    DrawRoseDiagram();
                    //cmdCreatePvPole.Enabled = true;
                    //----------------------------------------------------------------------
                    map.ViewExtents = ext;
                    siteLocatedbyCentroid = true;
                }
                catch
                {
                }
            }
        }

        void DrawRoseDiagram()
        {
            
           // CheckWorkingPath();

            //if (prj.Path != "")
           // {
              // lblTab03.Enabled = true;
              //  lblTab04.Enabled = true;
              //  lblTab05.Enabled = true;
              //  prj.Verify[3] = true;

                pickBLLocation = false;
                App.ProgressHandler.Progress("Creating Sun Rose Diagram", 0, "Creating Sun Rose Diagram");
                RoseChart rc = new RoseChart();

                System.Data.DataTable table = new System.Data.DataTable("SolarTab");
                table.Columns.Add(new DataColumn("DIR", typeof(string)));
                for (int i = 1; i <= 8; i++)
                {
                    table.Columns.Add(new DataColumn(rc.getStrMagnitude(i), typeof(int)));
                }
                table.Columns.Add(new DataColumn("Total", typeof(int)));
                //------------------------------------------------------------
                Int16[,] sunHr = new Int16[9, 17];

                DateTime today = DateTime.Today;
                int year = today.Year;

                //Todo: Check site location data before run

                double Latitude = prj.Latiude;
                double Longitude = prj.Longtitude;
                double UtmN = prj.UtmN;
                double UtmE = prj.UtmE;
               // if (util.IsNumeric(this.txtRoseScale.Text) == false) txtRoseScale.Text = "1";  //Set scale = 1 for default
               // double RoseScale = Convert.ToDouble(this.txtRoseScale.Text);

                short TimeZone = -7;
                Int32 nightHr = 0;
                Int32 noonHr = 0;
                for (int month = 1; month <= 12; month++)
                {
                    int month_day = System.DateTime.DaysInMonth(2001, month);
                    for (int day = 1; day <= month_day; day++)
                    {
                        for (int hr = 0; hr < 24; hr++)
                        {
                            double hrPassMidnight = (double)hr / 24.0;
                            SolarCal ySolar = new SolarCal(day, month, year, hrPassMidnight, Latitude, Longitude, TimeZone);
                            //SolarCal ySolar = new SolarCal(day, month, year, hrPassMidnight, Latitude, Longitude, TimeZone);
                            double eleAng = ySolar.SolarElevationAngle;
                            double AzAng = ySolar.SolarAzimuthAngle;
                            //--------------------------------------------------------------
                            if (eleAng > 0)
                            {
                                noonHr++;
                                string AzName = rc.AzName(AzAng);
                                int iRow = rc.AZNameID(AzAng);
                                int iCol = rc.iEleAng(eleAng);
                                sunHr[iCol, iRow]++;
                            }
                            else // Night hour
                            {
                                nightHr++;
                            }
                        }
                    }
                }
                //txtNoonHr.Text = noonHr.ToString();
                //txtNightHr.Text = nightHr.ToString();
                Int16 sumTotal = 0;
                for (int i = 0; i <= 15; i++)
                {
                    Int16 Total = 0;
                    for (int j = 1; j <= 8; j++) { Total += sunHr[j, i]; }
                    sumTotal += Total;
                    double Ang = i * 22.5;
                    table.Rows.Add(rc.AzName(Ang), sunHr[1, i], sunHr[2, i], sunHr[3, i], sunHr[4, i], sunHr[5, i], sunHr[6, i], sunHr[7, i], sunHr[8, i], Total);
                }
                table.Rows.Add("Sum", sunHr[1, 16], sunHr[2, 16], sunHr[3, 16], sunHr[4, 16], sunHr[5, 16], sunHr[6, 16], sunHr[7, 16], sunHr[8, 16], sumTotal);

                //-----------------------------------------------------
                //                grdSolarRose.DataSource = table;
                //-----------------------------------------------------
                //if (chkRosePlot.Checked == true)
                //{
                    Feature f = new Feature();
                    FeatureSet fea = new FeatureSet(f.FeatureType);
                    //RoseChart roseFeature = new RoseChart(Latitude, Longitude, table, sumTotal);
                    RoseChart roseFeature = new RoseChart(UtmN, UtmE, table, sumTotal, 1); // last argument was dynamically linked with a text box but has been removed.
                    fea = roseFeature.RoseFrature;
                    fea.Projection = map.Projection;
                    //MessageBox.Show(fea.ToString);  

                    //+++++++++++++++++++++++++++++++++++++++++++++++++++++
                    fea.Name = "Solar Radiation Rose";
                    fea.Filename = "C:\\" + "\\Temp\\" + fea.Name + ".shp";
                    //+++++++++++++++++++++++++++++++++++++++++++++++++++++

                    fea.SaveAs(fea.Filename, true);
                    util.removeDupplicateLyr(fea.Name, map);
                    /*
                    PolygonCategory polyCatalog = new PolygonCategory(Color.Red,Color.Yellow,1);
                    polyCatalog.FilterExpression = "Ele_angle";
                    PolygonScheme scheme = new PolygonScheme();
                    scheme.ClearCategories();
                    scheme.AddCategory(polyCatalog);

                    MapPolygonLayer RoseDiagram;
                    RoseDiagram = new MapPolygonLayer(fea);// MapPolygonLayer(fs);
                    RoseDiagram.SetCategory(fea,polyCatalog);
                    
                     */

                    map.Layers.Add(fea);

                    int iLyr = util.getLayerHdl(fea.Name, map);

                    IMapPolygonLayer RoseLayer = map.Layers[iLyr] as IMapPolygonLayer;

                    PolygonScheme PolyScheme = new PolygonScheme();
                    //linkScheme.Categories.Clear();
                    PolyScheme.EditorSettings.ClassificationType = ClassificationType.UniqueValues;
                    /*
                    if (j == 1) { return "<10"; }
                    if (j == 2) { return "10-20"; }
                    if (j == 3) { return "20-30"; }
                    if (j == 4) { return "30-40"; }
                    if (j == 5) { return "40-50"; }
                    if (j == 6) { return "50-60"; }
                    if (j == 7) { return "60-70"; }
                    if (j == 8) { return ">70"; }
              */
                    PolyScheme.EditorSettings.FieldName = "Ele_angle";
                    PolyScheme.CreateCategories(RoseLayer.DataSet.DataTable);

                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level00 = new PolygonSymbolizer(Color.RoyalBlue, Color.Black, 1);
                    _Level00.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level00 = new PolygonCategory(Color.RoyalBlue, Color.Black, 1);
                    Level00.FilterExpression = "[Ele_angle] = '<10'";
                    Level00.LegendText = "<10 degrees";

                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level01 = new PolygonSymbolizer(Color.PaleTurquoise, Color.Black, 1);
                    _Level01.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level01 = new PolygonCategory(Color.PaleTurquoise, Color.Black, 1);
                    Level01.FilterExpression = "[Ele_angle] = '10-20'";
                    Level01.LegendText = "10-20 degrees";
                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level02 = new PolygonSymbolizer(Color.PaleGreen, Color.Black, 1);
                    _Level02.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level02 = new PolygonCategory(Color.PaleGreen, Color.Black, 1);
                    Level02.FilterExpression = "[Ele_angle] = '20-30'";
                    Level02.LegendText = "20-30 degrees";
                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level03 = new PolygonSymbolizer(Color.PaleGoldenrod, Color.Black, 1);
                    _Level03.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level03 = new PolygonCategory(Color.PaleGoldenrod, Color.Black, 1);
                    Level03.FilterExpression = "[Ele_angle] = '30-40'";
                    Level03.LegendText = "30-40 degrees";
                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level04 = new PolygonSymbolizer(Color.Orange, Color.Black, 1);
                    _Level04.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level04 = new PolygonCategory(Color.Orange, Color.Black, 1);
                    Level04.FilterExpression = "[Ele_angle] = '40-50'";
                    Level04.LegendText = "40-50 degrees";
                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level05 = new PolygonSymbolizer(Color.Red, Color.Black, 1);
                    _Level05.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level05 = new PolygonCategory(Color.Red, Color.Black, 1);
                    Level05.FilterExpression = "[Ele_angle] = '50-60'";
                    Level05.LegendText = "50-60 degrees";
                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level06 = new PolygonSymbolizer(Color.Crimson, Color.Black, 1);
                    _Level06.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level06 = new PolygonCategory(Color.Crimson, Color.Black, 1);
                    Level06.FilterExpression = "[Ele_angle] = '60-70'";
                    Level06.LegendText = "60-70 degrees";
                    //--------------------------------------------------------------------------------
                    PolygonSymbolizer _Level07 = new PolygonSymbolizer(Color.DarkRed, Color.Black, 1);
                    _Level07.ScaleMode = ScaleMode.Simple;
                    PolygonCategory Level07 = new PolygonCategory(Color.DarkRed, Color.Black, 1);
                    Level07.FilterExpression = "[Ele_angle] = '>70'";
                    Level07.LegendText = ">70 degrees";
                    //--------------------------------------------------------------------------------
                    PolyScheme.ClearCategories();
                    PolyScheme.AddCategory(Level00);
                    PolyScheme.AddCategory(Level01);
                    PolyScheme.AddCategory(Level02);
                    PolyScheme.AddCategory(Level03);
                    PolyScheme.AddCategory(Level04);
                    PolyScheme.AddCategory(Level05);
                    PolyScheme.AddCategory(Level06);
                    PolyScheme.AddCategory(Level07);


                    RoseLayer.Symbology = PolyScheme;
                    RoseLayer.DataSet.InvalidateVertices();
                    //-------------------------------------------------------------------
                    //pvMap.MapFrame.DrawingLayers.Clear();
                    //pvMap.MapFrame.DrawingLayers.Add(RoseLayer);
                    //pvMap.MapFrame.Invalidate();

              //}
                //------------------------------
                //                YearlyCal();
                //verify[3] = true;
                App.ProgressHandler.Progress("Sun Rose created", 0, "");
                //cmdSwithToGraph.Visible = true; todo: figure out how to add button to map and toggle it
         // }
        }

    }
}
